use crate::dto::{Response, ResponseCode};
use std::fmt::{Debug, Display, Formatter};

#[derive(Debug)]
pub struct ErrorBacktrace(std::backtrace::Backtrace);

impl Display for ErrorBacktrace {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        Display::fmt(&self.0, f)
    }
}

impl Default for ErrorBacktrace {
    fn default() -> Self {
        ErrorBacktrace(std::backtrace::Backtrace::force_capture())
    }
}

#[derive(thiserror::Error)]
#[error("{code} {message}\n{backtrace}")]
pub struct ResponseError {
    pub code: ResponseCode,
    pub message: String,
    pub backtrace: ErrorBacktrace,
}

impl From<&ResponseError> for Response<()> {
    fn from(value: &ResponseError) -> Self {
        Self {
            code: value.code.clone(),
            message: value.message.clone(),
            data: (),
        }
    }
}

impl Debug for ResponseError {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        Display::fmt(self, f)
    }
}

impl ResponseError {
    pub fn filter_can_not_be_empty() -> Self {
        Self {
            code: ResponseCode::BAD_REQUEST,
            message: "筛选条件不能都为空".to_string(),
            backtrace: Default::default(),
        }
    }

    pub fn internal_server_error() -> Self {
        Self {
            code: ResponseCode::INTERNAL_ERROR,
            message: "内部错误".to_string(),
            backtrace: Default::default(),
        }
    }

    pub fn the_endpoint_type_only_have_one() -> Self {
        Self {
            code: ResponseCode::BAD_REQUEST,
            message: "该endpoint_type只能有一个".to_string(),
            backtrace: Default::default(),
        }
    }

    pub fn endpoint_not_found(endpoint_id: &str) -> Self {
        Self {
            code: ResponseCode::NOT_FOUND,
            message: format!("endpoint不存在，endpoint_id={}", endpoint_id),
            backtrace: Default::default(),
        }
    }

    pub fn endpoint_already_exist(endpoint_id: &str) -> Self {
        Self {
            code: ResponseCode::BAD_REQUEST,
            message: format!("endpoint已存在，endpoint_id={}", endpoint_id),
            backtrace: Default::default(),
        }
    }

    pub fn endpoint_peer_not_found(endpoint_peer_id: &str) -> Self {
        Self {
            code: ResponseCode::NOT_FOUND,
            message: format!("endpoint.peer不存在，endpoint_peer_id={}", endpoint_peer_id),
            backtrace: Default::default(),
        }
    }

    pub fn endpoint_peer_already_exists(endpoint_id: &str, peer_endpoint_id: &str) -> Self {
        Self {
            code: ResponseCode::BAD_REQUEST,
            message: format!(
                "endpoint.peer已存在，endpoint_id={}, peer_endpoint_id={}",
                endpoint_id, peer_endpoint_id
            ),
            backtrace: Default::default(),
        }
    }

    pub fn endpoint_wireguard_config_already_exist(endpoint_id: &str) -> Self {
        Self {
            code: ResponseCode::BAD_REQUEST,
            message: format!(
                "endpoint.wireguard_config已存在，endpoint_id={}",
                endpoint_id
            ),
            backtrace: Default::default(),
        }
    }

    pub fn endpoint_wireguard_config_not_found(endpoint_id: &str) -> Self {
        Self {
            code: ResponseCode::NOT_FOUND,
            message: format!(
                "endpoint.wireguard_config不存在，endpoint_id={}",
                endpoint_id
            ),
            backtrace: Default::default(),
        }
    }

    pub fn endpoint_peer_wireguard_config_not_found(endpoint_peer_id: &str) -> Self {
        Self {
            code: ResponseCode::NOT_FOUND,
            message: format!(
                "endpoint.peer.wireguard_config不存在，endpoint_peer_id={}",
                endpoint_peer_id
            ),
            backtrace: Default::default(),
        }
    }

    pub fn endpoint_srv6_config_already_exist(endpoint_id: &str) -> Self {
        Self {
            code: ResponseCode::BAD_REQUEST,
            message: format!("endpoint.srv6_config已存在，endpoint_id={}", endpoint_id),
            backtrace: Default::default(),
        }
    }

    pub fn endpoint_srv6_config_not_found(endpoint_id: &str) -> Self {
        Self {
            code: ResponseCode::NOT_FOUND,
            message: format!("endpoint.srv6_config不存在，endpoint_id={}", endpoint_id),
            backtrace: Default::default(),
        }
    }

    pub fn te_policy_group_not_found(te_policy_group_id: &str) -> Self {
        Self {
            code: ResponseCode::NOT_FOUND,
            message: format!(
                "te_policy_group不存在，te_policy_group_id={}",
                te_policy_group_id
            ),
            backtrace: Default::default(),
        }
    }

    pub fn candidate_path_not_found(candidate_path_id: &str) -> Self {
        Self {
            code: ResponseCode::NOT_FOUND,
            message: format!(
                "candidate_path不存在，candidate_path_id={}",
                candidate_path_id
            ),
            backtrace: Default::default(),
        }
    }

    pub fn segment_list_not_found(segment_list_id: &str) -> Self {
        Self {
            code: ResponseCode::NOT_FOUND,
            message: format!("segment_list不存在，segment_list_id={}", segment_list_id),
            backtrace: Default::default(),
        }
    }

    pub fn network_acl_not_found(network_acl_id: &str) -> Self {
        Self {
            code: ResponseCode::NOT_FOUND,
            message: format!("network_acl不存在，network_acl_id={}", network_acl_id),
            backtrace: Default::default(),
        }
    }

    pub fn traffic_steering_rule_not_found(traffic_steering_rule_id: &str) -> Self {
        Self {
            code: ResponseCode::NOT_FOUND,
            message: format!(
                "traffic_steering_rule不存在，traffic_steering_rule_id={}",
                traffic_steering_rule_id
            ),
            backtrace: Default::default(),
        }
    }
}

#[derive(thiserror::Error, Debug)]
#[error("{code} {message}\n{source:?}")]
pub struct ResponseErrorAny {
    pub code: ResponseCode,
    pub message: String,
    pub source: anyhow::Error,
}
